package com.zzyk.main.configuration.aspectj;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.zzyk.main.configuration.aspectj.annotation.OperaLog;

import com.zzyk.main.model.pojo.*;
import com.zzyk.main.model.vo.OrganizationInfo;
import com.zzyk.main.service.*;
import com.zzyk.main.utils.IPUtils;
import com.zzyk.main.utils.SpringUtils;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 用于切面将日志写入数据库
 */
@Aspect
@Component
@EnableAsync
public class LogAspect {

    @Autowired
    private ISysLogService sysLogService;

    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private CompanyService companyService;

    @Autowired
    private ISysRoleService sysRoleService;

    @Resource
    private MaintenanceInfoService maintenanceInfoService;

    @Pointcut(value = "@annotation(com.zzyk.main.configuration.aspectj.annotation.OperaLog)")
    public void pointCut() {
    }

    @Around("pointCut()&&@annotation(operaLog)")
    public Object record(ProceedingJoinPoint target, OperaLog operaLog) throws Throwable {
        if (operaLog == null) {
            return target.proceed();
        }
        Object result = null;
        SysLog sysLog = new SysLog();
        SysUser authUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
        if (authUser != null) {
            sysLog.setUserId(authUser.getId());
        }
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();//获取request
//        sysLog.setUserIp(SecurityUtils.getSubject().getSession().getHost());
        sysLog.setUserIp(IPUtils.getIpAddr(request));
        sysLog.setOpera(operaLog.value());
        String className = target.getTarget().getClass().getName();
        String methodName = target.getSignature().getName();
        sysLog.setMethod(className + "." + methodName + "()");
        sysLog.setUrl(SpringUtils.getRequestAttributes().getRequest().getRequestURI());
        Map<String, String[]> map = SpringUtils.getRequestAttributes().getRequest().getParameterMap();
        String params = JSONObject.toJSONString(map);
        if (params.length() > 255) {
            params = params.substring(0, 254);
        }
        sysLog.setParams(params);
        Object[] args = target.getArgs();
        SysUser user = null;
        String sn = "";
        String deviceName = "";
        MaintenanceInfo maintenanceInfo;
        Device device;
        OrganizationInfo organizationInfo;
        SysRole sysRole;
        Company company;
        DeviceType deviceType;
        switch (methodName) {
            case "login":
                sysLog.setDesc("用户名[" + args[0] + "]");
                break;
            case "changePassword":
                sysLog.setDesc("用户名[" + authUser.getUsername() + "]");
                break;
            case "addUser":
                user = (SysUser) args[0];
                if (user.getUsername() != null) {
                    sysLog.setDesc("用户名[" + user.getUsername() + "]");
                }
                break;
            case "updateUser":
                user = (SysUser) args[0];
                if (user != null && user.getId() != null) {
                    user = sysUserService.getUser(user.getId());
                    sysLog.setDesc("用户名[" + user.getUsername() + "]");
                } else {
                    sysLog.setDesc("未知用户");
                }
                break;
            case "deleteUser":
                Integer userId = (Integer) args[0];
                if (userId != null) {
                    user = sysUserService.getUser(userId);
                    if (user != null) {
                        sysLog.setDesc("用户名[" + user.getUsername() + "]");
                    } else {
                        sysLog.setDesc("警告: 未知用户");
                    }
                }
                break;
            case "exportDeviceDataTable":
            case "exportLog":
                StringBuffer buffer = new StringBuffer();
                for (String key : map.keySet()) {
                    Object value = map.get(key)[0];
                    if (value != null && !"".equals(value)) {
                        switch (key) {
                            case "startTime":
                                buffer.append("开始时间");
                                break;
                            case "endTime":
                                buffer.append("结束时间");
                                break;
                            case "searchValue":
                                buffer.append("查询关键字");
                                break;
                            case "operation":
                                buffer.append("操作类型");
                                break;
                            default:
                                buffer.append(key);
                        }
                        buffer.append("=");
                        buffer.append(map.get(key)[0]);
                        buffer.append(";");
                    }
                }
                sysLog.setDesc(buffer.toString());
                break;
            case "saveOrUpdateCollectionMaintenance":
                maintenanceInfo = (MaintenanceInfo) args[0];

                if (ObjectUtil.isNotNull(maintenanceInfo.getSn())) {
                    sn = maintenanceInfo.getSn();
                    deviceName = deviceService.selectDeviceByNumber(sn, 0).getName();
                }
                sysLog.setDesc("设备名称[" + deviceName + "]");
                if (maintenanceInfo.getMethodType() == 0) {
                    sysLog.setOpera("添加采集设备维保信息");
                } else {
                    sysLog.setOpera("修改采集设备维保信息");
                }
                break;
            case "saveProductionEquipment":
                device = (Device) args[0];
                sysLog.setDesc("设备名称[" + device.getName() + "]");
                if (device.getMethodType() == 0) {
                    sysLog.setOpera("添加设备信息");
                } else {
                    sysLog.setDesc("设备名称[" + device.getName() + "]，设备ID[" + device.getId() + "]");
                    sysLog.setOpera("修改设备信息");
                }
                break;
            case "saveCollectionEquipment":
                if (ObjectUtil.isNotNull(map.get("name")[0])) {
                    deviceName = map.get("name")[0];
                }
                sysLog.setDesc("设备名称[" + deviceName + "]");
                break;
            case "updateCollectionEquipment":
                if (ObjectUtil.isNotNull(map.get("name")[0])) {
                    deviceName = map.get("name")[0];
                }
                sysLog.setDesc("设备名称[" + deviceName + "]");
                break;
            case "saveOrUpdateMaintenance":
                maintenanceInfo = (MaintenanceInfo) args[0];
                if (ObjectUtil.isNotNull(maintenanceInfo)) {
                    sn = maintenanceInfo.getSn();
                    deviceName = deviceService.selectDeviceByNumber(sn, 1).getName();
                }
                sysLog.setDesc("设备名称[" + deviceName + "]");
                if (maintenanceInfo.getMethodType() == 0) {
                    sysLog.setOpera("添加生产设备维保记录");
                } else {
                    sysLog.setOpera("修改生产设备维保记录");
                }
                break;
            case "deleteDevice":
                if (ObjectUtil.isNotNull(map.get("id")[0])) {
                    deviceName = deviceService.selectByPrimaryKey(Integer.parseInt(map.get("id")[0])).getName();
                }
                sysLog.setDesc("设备名[" + deviceName + "]");
                break;
            case "deleteMaintenance":
                MaintenanceInfo maintenance = maintenanceInfoService.selectByPrimaryKey((Integer) args[0]);
                deviceName = deviceService.selectDeviceByNumber(maintenance.getSn(), 1).getName();
                sysLog.setDesc("设备名[" + deviceName + "]");
                break;
            case "save":
                organizationInfo = (OrganizationInfo) args[0];
                sysLog.setDesc("企业名称[" + organizationInfo.getName() + "]");
                if (ObjectUtil.isNotNull(organizationInfo.getId())) {
                    sysLog.setOpera("修改企业信息");
                } else {
                    sysLog.setOpera("添加企业信息");
                }
                break;
            case "deleteInfoById":
                company = companyService.selectByPrimaryKey((Integer) args[0]);
                if (ObjectUtil.isNotNull(company)) {
                    sysLog.setDesc("企业名称[" + company.getName() + "]");
                }
                break;
            case "saveRole":
                sysRole = (SysRole) args[0];
                sysLog.setDesc("角色名[" + sysRole.getRoleName() + "]");
                if (ObjectUtil.isNotNull(sysRole.getId())) {
                    sysLog.setOpera("修改角色信息");
                } else {
                    sysLog.setOpera("添加角色信息");
                }
                break;
            case "delRole":
                SysRole role = sysRoleService.getRole((Integer) args[0]);
                sysLog.setDesc("角色名[" + role.getRoleName() + "]");
                break;
            case "saveUser":
                user = (SysUser) args[0];
                sysLog.setDesc("用户名[" + user.getUsername() + "]");
                if (ObjectUtil.isNull(user.getId())) {
                    sysLog.setOpera("添加用户信息");
                }
                break;
            case "saveOrUpdateTimeRule":
                sysLog.setDesc("用户名[" + authUser.getUsername() + "]");
                Integer eId;
                if ((Integer) args[4] == 1) {
                    sysLog.setOpera("修改企业作息时间规则");
                    eId = (Integer) args[5];
                } else {
                    eId = (Integer) args[0];
                    sysLog.setOpera("添加企业作息时间规则");
                }
                company = companyService.selectByPrimaryKey(eId);
                if (ObjectUtil.isNotNull(company)) {
                    sysLog.setDesc("企业名称[" + company.getName() + "]");
                }
                break;
            case "deleteInfo":
                sysLog.setDesc("用户名[" + authUser.getUsername() + "]");
                company = companyService.selectByPrimaryKey((Integer) args[0]);
                if (ObjectUtil.isNotNull(company)) {
                    sysLog.setDesc("企业名称[" + company.getName() + "]");
                }
                break;
            case "clearElectric":
            case "restartDevice":
            case "remoteResetAlarm":
                device = deviceService.selectByPrimaryKey((Integer) args[0]);
                if (ObjectUtil.isNotNull(device)) {
                    sysLog.setDesc("设备名称[" + device.getName() + "]");
                }
                break;
            case "updateDeviceConfig":
                sysLog.setDesc("用户名[" + authUser.getUsername() + "]");
                sysLog.setOpera("修改采集设备配置信息");
                DeviceParam deviceParam = (DeviceParam) args[0];
                if (ObjectUtil.isNotNull(deviceParam)) {
                    device = deviceService.selectByPrimaryKey(deviceParam.getDeviceID());
                    if (ObjectUtil.isNotNull(device)) {
                        sysLog.setDesc("设备名称[" + device.getName() + "]");
                    }
                }
                break;
            case "insertDeviceType":
            case "updateDeviceTypeById":
                deviceType = (DeviceType) args[0];
                if (ObjectUtil.isNotNull(deviceType)) {
                    if (ObjectUtil.isNotNull(deviceType.getIsDelete()) && deviceType.getIsDelete() == 1) {
                        sysLog.setOpera("删除设备类型");
                    }
                    sysLog.setDesc("类型名称[" + deviceType.getTitle() + "]");
                }
                break;
        }
        try {
            result = target.proceed();
            authUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
            if (sysLog.getUserId() == null && authUser != null) {
                sysLog.setUserId(authUser.getId());
            }
            sysLog.setResult(0);
            return result;
        } catch (Throwable t) {
            t.printStackTrace();
            sysLog.setResult(1);
            if (t.getMessage() != null) {
                if (t.getMessage().length() > 255) {
                    sysLog.setError(t.getMessage().substring(0, 254));
                } else {
                    sysLog.setError(t.getMessage());
                }
            } else {
                sysLog.setError(t.getClass().getName());
            }
            throw t;
        } finally {
            sysLogService.addLog(sysLog);
        }
    }
}
